import { hasOneOf } from "@/libs/index";
import { mapState } from "vuex";

/**
 * 菜单
 * @param {*} list 通过路由列表得到菜单列表,权限匹配则生成对应菜单
 * @param {*} access 用户访问权限
 * @param {*} isAdmin 是否超级管理员
 */
export const getMenusByRouters = (list = [], access = [], isAdmin = false) => {
    let menus = []
    list.forEach(item => {
        if(item.meta && !item.meta.hideInMenu) {
            let menu = {
                path: item.path,
                name: item.name,
                meta: item.meta
            }
            // 子菜单
            if(hasChild(item) && (item.meta && !item.meta.hideInMenu) && showThisMenuEle(item, access, isAdmin)) {
                menu.children = getMenusByRouters(item.children, access, isAdmin)
            }

            // 一级菜单
            if (showThisMenuEle(item, access, isAdmin)) {
                menus.push(menu)
            }
        }
    });
    return menus;
}

/**
 * 菜单是否包含子菜单
 * @param {*} item
 */
const hasChild = (item) => {
    return item.children && item.children.length !== 0
}

/**
 * 判断该菜单是否显示，根据权限决定
 * @param {*} item 菜单
 * @param {*} access 权限组
 * @param {*} isAdmin 是否超级管理员
 */
const showThisMenuEle = (item, access, isAdmin) => {
    if(isAdmin) {
        return true
    } else {
        if (item.meta && item.meta.access && item.meta.access.length) {
            if (hasOneOf(item.meta.access, access)) {
                return true
            } else {
                return false
            }
        } else {
            return true
        }
    }
}


/**
 * @description 本地存储和获取标签导航列表
 */
export const setTagNavListInLocalstorage = list => {
    localStorage.tagNaveList = JSON.stringify(list)
}
/**
 * @returns {Array} 其中的每个元素只包含路由原信息中的name, path, meta三项
 */
export const getTagNavListFromLocalstorage = () => {
    const list = localStorage.tagNaveList
    return list ? JSON.parse(list) : []
}

/**
 * @param {*} list 现有标签导航列表
 * @param {*} newRoute 新添加的路由原信息对象
 * @description 如果该newRoute已经存在则不再添加
 */
export const getNewTagList = (list, newRoute) => {
    const { name, path, meta } = newRoute
    let newList = [...list]
    if (newList.findIndex(item => item.name === name) >= 0) return newList
    else newList.push({ name, path, meta })
    return newList
}


/**
 * @param {Array} routeMetched 当前路由metched
 * @returns {Array}
 */
export const getBreadCrumbList = (routeMetched, homeRoute) => {
    let res = routeMetched.filter(item => {
        return item.meta === undefined || !item.meta.hide
    }).map(item => {
        let obj = {
            icon: (item.meta && item.meta.icon) || '',
            name: item.name,
            meta: item.meta
        }
        return obj
    })
    res = res.filter(item => {
        return !item.meta.hideInMenu
    })
    return [homeRoute, ...res]
}


/**
 * @description 根据name/params/query判断两个路由对象是否相等
 * @param {*} route1 路由对象
 * @param {*} route2 路由对象
 */
export const routeEqual = (route1, route2) => {
    const params1 = route1.params || {}
    const params2 = route2.params || {}
    const query1 = route1.query || {}
    const query2 = route2.query || {}
    return (route1.name === route2.name) && objEqual(params1, params2) && objEqual(query1, query2)
}



/**
 * 判断打开的标签列表里是否已存在这个新添加的路由对象
 */
export const routeHasExist = (tagNavList, routeItem) => {
    let len = tagNavList.length
    let res = false
    doCustomTimes(len, (index) => {
        if (routeEqual(tagNavList[index], routeItem)) res = true
    })
    return res
}


/**
 * @param {*} obj1 对象
 * @param {*} obj2 对象
 * @description 判断两个对象是否相等，这两个对象的值只能是数字或字符串
 */
export const objEqual = (obj1, obj2) => {
    const keysArr1 = Object.keys(obj1)
    const keysArr2 = Object.keys(obj2)
    if (keysArr1.length !== keysArr2.length) return false
    else if (keysArr1.length === 0 && keysArr2.length === 0) return true
    else return !keysArr1.some(key => obj1[key] != obj2[key])
}


/**
 * @param {Array} list 标签列表
 * @param {String} name 当前关闭的标签的name
 */
export const getNextRoute = (list, route) => {
    let res = {}
    if (list.length === 2) {
        res = getHomeRoute(list)
    } else {
        const index = list.findIndex(item => routeEqual(item, route))
        if (index === list.length - 1) res = list[list.length - 2]
        else res = list[index + 1]
    }
    return res
}

/**
 * @param {Array} routers 路由列表数组
 * @description 用于找到路由列表中name为home的对象
 */
export const getHomeRoute = routers => {
    let i = -1
    let len = routers.length
    let homeRoute = {}
    while (++i < len) {
        let item = routers[i]
        if (item.children && item.children.length) {
            let res = getHomeRoute(item.children)
            if (res.name) return res
        } else {
            if (item.name === 'console') homeRoute = item
        }
    }
    return homeRoute
}

/**
 * @param {Number} times 回调函数需要执行的次数
 * @param {Function} callback 回调函数
 */
export const doCustomTimes = (times, callback) => {
    let i = -1
    while (++i < times) {
        callback(i)
    }
}

